#pragma once

#include "noncopyable.h"
#include "Timestamp.h"
#include "CurrentThread.h"

#include <functional>
#include <vector>
#include <atomic>
#include <memory>
#include <mutex>

class Channel;
class Poller;
class TimerQeueu;

// 事件循环类 主要包含了两大模块 Channel Poller(epoll的抽象)
class EventLoop : noncopyable
{
public:
    using Functor = std::function<void()>;
    EventLoop();
    ~EventLoop();

    // 开启事件循环
    void loop();
    // 退出事件循环
    void quit();

    Timestamp pollReturnTime() const { return pollReturnTime_; }

    // 当前线程中执行
    void runInLoop(Functor cb);
    // 把cb放入队列中,唤醒loop所在线程,执行cb
    void queueInLoop(Functor cv);
    // 唤醒loop所在线程
    void wakeup();
    
    // eventloop方法-> poller方法
    void updateChannel(Channel *channel);
    void removeChannel(Channel *channel);
    bool hasChannel(Channel *channel);
    // 判断loop是否在自己的线程里面
    bool isInLoopThread() const { return threadId_ == CurrentThread::tid(); }

private:
    void handleRead();
    void doPendingFunctors();


    using ChannelList = std::vector<Channel *>;

    std::atomic_bool looping_;                /* atomic */
    std::atomic_bool quit_;                   // 标志退出loop循环
    std::atomic_bool callingPendingFunctors_; // 标识当前loop是否有需要执行的回调操作
    const pid_t threadId_;                    // 记录当前loop所在线程id
    Timestamp pollReturnTime_;                // poller返回发生事件的channels的时间
    std::unique_ptr<Poller> poller_;

    int wakeupFd_; // 当main loop获取一个新用户的channel,通过轮询算法选择一个subloop,通过该成员唤醒subloop处理channel
    std::unique_ptr<Channel> wakeupChannel_;

    ChannelList activeChannels_;

    std::vector<Functor> pendingFunctors_; // 存储loop需要执行的所有回调操作
    std::mutex mutex_;                     // mutex用来保护上面vector容器的线程安全
};
